package com.whatisjee.ssf.domain.dao.impl;

import static org.apache.commons.lang.StringUtils.isNotBlank;

import java.util.List;

import com.whatisjee.ssf.domain.dao.UserDao;
import com.whatisjee.ssf.domain.entity.User;
import com.whatisjee.ssf.misc.Page;
import com.whatisjee.ssf.misc.UserCriteria;
import javax.enterprise.context.ApplicationScoped;
import javax.inject.Named;
import javax.persistence.Query;

@Named("userDao")
@ApplicationScoped
public class UserDaoImpl extends AbstractDaoImpl implements UserDao {

	@Override
	public void save(User user) {
		em.persist(user);
	}

	@Override
	public User select(final String name) {
                String hql = "from User where name = :name";
                Query q = em.createQuery(hql);
                q.setParameter("name", name);
                return (User) q.getSingleResult();
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<User> select(final UserCriteria criteria, final Page page) {
                StringBuilder sb = new StringBuilder("SELECT a ");
                buildHql(sb, criteria);
                Query q = createPagedQuery(page, sb, "a");
                setParameters(q, criteria);
                return q.getResultList();
	}

	@Override
	public int selectCount(final UserCriteria criteria) {
                StringBuilder sb = new StringBuilder("SELECT COUNT(a) ");
                buildHql(sb, criteria);
                Query q = em.createQuery(sb.toString());
                setParameters(q, criteria);
                return ((Number) q.getSingleResult()).intValue();
	}

	private void buildHql(StringBuilder sb, UserCriteria criteria) {
		sb.append(" FROM User a WHERE 1=1 ");
		if(isNotBlank(criteria.getName())) {
			sb.append(" AND a.name LIKE :name ");
		}
		if(isNotBlank(criteria.getFirstName())) {
			sb.append(" AND a.firstName = :firstName ");
		}
		if(isNotBlank(criteria.getLastName())) {
			sb.append(" AND a.lastName = :lastName ");
		}
	}
	
	private void setParameters(Query q, UserCriteria criteria) {
		if(isNotBlank(criteria.getName())) {
			q.setParameter("name", "%" + criteria.getName() + "%");
		}
		if(isNotBlank(criteria.getFirstName())) {
			q.setParameter("firstName", criteria.getFirstName());
		}
		if(isNotBlank(criteria.getLastName())) {
			q.setParameter("lastName", criteria.getLastName());
		}
	}

	@Override
	public User select(Integer id) {
		return em.find(User.class, id);
	}
}
